<?php

declare(strict_types=1);

namespace App\Master\Framework\Library\Easywechat;

use EasyWeChat\Pay\Application;
use EasyWeChat\Kernel\Contracts\Config;

class PayService extends EasyModule
{
    protected Application $app;
    protected Config      $config;

    /**
     * 实例化
     */
    public function __construct()
    {
        parent::__construct();

        $this->app    = $this->pay();
        $this->config = $this->app->getConfig();
    }

    /**
     * 支付 server
     * @return \EasyWeChat\Kernel\Contracts\Server|\EasyWeChat\Pay\Server
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \ReflectionException
     * @throws \Throwable
     */
    public function getServer()
    {
        return $this->app->getServer();
    }

    /**
     * 统一下单
     *
     * @param string $openid
     * @param string $out_trade_no
     * @param int $fee
     * @param string $description
     * @param string $notify_url
     * @return bool
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
     */
    public function jsapi(string $openid, string $out_trade_no, int $fee = 0, string $description = '', string $notify_url = '')
    {
        $app = $this->app;

        $api = $app->getClient();

        $response = $api->postJson("v3/pay/transactions/jsapi", [
            'mchid'        => (string)$this->config['mch_id'],         // <---- 请修改为您的【子商户号/二级商户号】由微信支付生成并下发。
            "out_trade_no" => $out_trade_no,                           // 外部商户订单号
            "appid"        => (string)$this->config['app_id'],         // <---- 请修改为【子商户号/二级商户号】服务号的 appid
            "description"  => $description,
            "notify_url"   => $notify_url,// 回调地址
            "amount"       => [
                "total"    => $fee,
                "currency" => "CNY"
            ],
            "payer"        => [
                "openid" => $openid, // <---- 【用户子标识】 用户在子商户AppID下的唯一标识。若传sub_openid，那sub_appid必填。下单前需获取到用户的OpenID
            ]
        ]);

        if (!$this->response($response)) {
            return false;
        }

        if (empty($this->data['prepay_id'])) {
            return false;
        }

        $appId      = (string)$this->config['app_id'];
        $signType   = 'RSA'; // 默认RSA，v2要传MD5
        $utils      = $app->getUtils();
        $this->data = $utils->buildBridgeConfig($this->data['prepay_id'], $appId, $signType); // 返回数组

        return true;
    }

    /**
     * App下单
     * TODO 有待测试
     * @param string $out_trade_no
     * @param int $fee
     * @param string $description
     * @param string $notify_url
     * @return bool
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     */
    public function appPay(string $out_trade_no, int $fee = 0, string $description = '', string $notify_url = '')
    {
        $app = $this->app;

        $api = $app->getClient();

        $response = $api->postJson("v3/pay/transactions/app", [
            "appid"        => $this->config['app_id'], // <---- 请修改为【子商户号/二级商户号】服务号的 appid
            'mchid'        => $this->config['mch_id'], // <---- 请修改为您的【子商户号/二级商户号】由微信支付生成并下发。
            "description"  => $description,
            "out_trade_no" => $out_trade_no,// 外部商户订单号
            "notify_url"   => $notify_url,  // 回调地址
            "amount"       => [
                "total"    => $fee,
                "currency" => "CNY"
            ]
        ])->throw(false);

        if (!$this->response($response)) {
            return false;
        }

        if (empty($this->data['prepay_id'])) {
            return false;
        }

        $appId      = $this->config['app_id'];
        $signType   = 'RSA'; // 默认RSA，v2要传MD5
        $utils      = $app->getUtils();
        $this->data = $utils->buildBridgeConfig($this->data['prepay_id'], $appId, $signType); // 返回数组

        return true;
    }

    /**
     * H5下单
     * TODO 有待完善
     * @param string $out_trade_no
     * @param int $fee
     * @param string $description
     * @param string $notify_url
     * @return bool
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     */
    public function h5Pay(string $out_trade_no, int $fee = 0, string $description = '', string $notify_url = '')
    {
        $app = $this->app;

        $api = $app->getClient();

        $response = $api->postJson("v3/pay/transactions/h5", [
            "appid"        => $this->config['app_id'], // <---- 请修改为【子商户号/二级商户号】服务号的 appid
            'mchid'        => $this->config['mch_id'], // <---- 请修改为您的【子商户号/二级商户号】由微信支付生成并下发。
            "description"  => $description,
            "out_trade_no" => $out_trade_no,// 外部商户订单号
            "notify_url"   => $notify_url,  // 回调地址
            "amount"       => [
                "total"    => $fee,
                "currency" => "CNY"
            ],
            "scene_info"   => [
                "payer_client_ip" => $_SERVER['HTTP_X_REAL_IP'] ?? Request::capture()->getClientIp(),
                ""
            ]
        ])->throw(false);

        if (!$this->response($response)) {
            return false;
        }

        if (empty($this->data['prepay_id'])) {
            return false;
        }

        $appId      = $this->config['app_id'];
        $signType   = 'RSA'; // 默认RSA，v2要传MD5
        $utils      = $app->getUtils();
        $this->data = $utils->buildBridgeConfig($this->data['prepay_id'], $appId, $signType); // 返回数组

        return true;
    }

    public function handlePaid(callable $function)
    {
        if (!$function()){
            return $this;
        }
    }
}